﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace new_problem
{
    internal class FastestWay
    {
        public static Double[,] CalcFastestWay(double[,] g, double[] x, double[] y, DataBuffer current)
        {
            double eps = 0.01; // рекомендуемая точность
            double alpha = 0.0001; // регуляризующий коэффициент
            Double[,] z0 = DataGen.StartApproximation(); // начальное приближение
            Double[,] zT = DataGen.GetSurfaceGrid(x, y); // теор.поле
            Double[,] A = DataGen.GetFieldGridBySurf(x, y, z0);
            Double[,] dA = DataGen.GetFieldDerivative(x, y, z0);
            Double[,] zk = new double[DataGen.N + 1, DataGen.N + 1]; // for result

            double nrm = MiscUtils.Norm(g); // ||g||
            //double nrm = Norm(zT);
            double err = 1.1;
            int k = 0;
            while (err > eps && k < 10000)
            {
                Double[,] S = MiscUtils.CalcS(A, dA, g);
                double num = MiscUtils.CalcNumerator(A, g);
                double den = MiscUtils.CalcDenominator(dA, S);
                double coef = alpha * (num / den);
                double stabFunc = 1.0; // DataGen.StabilisingFunctional(z0);
                for (int i = 0; i <= DataGen.N; i++)
                    for (int j = 0; j <= DataGen.N; j++)
                        zk[i, j] = z0[i, j] + coef *stabFunc *S[i, j];// ?

                z0 = zk;
                A = DataGen.GetFieldGridBySurf(x, y, z0);
                dA = DataGen.GetFieldDerivative(x, y, z0);
                err = MiscUtils.Norm(MiscUtils.SubstractMatrix(A, g));
                //err = Norm(SubstractMatrix(zk, zT));
                err /= nrm;

                alpha = 0.1;

                Console.WriteLine(k + ": " + err + ", alpha: " + alpha);
                k++;    
            }
            current.Fw = k;
            current.FwErr = err;
            return MiscUtils.SubstractMatrix(new double[DataGen.N + 1, DataGen.N + 1], zk);
        }
    }
}
